﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using Liang.Device.Model.Camera;
using Liang.Device.Camera;

namespace Liang.UI.CameraControl
{
    public delegate void PlayWindowLayoutChangedHandle(object sender, PlayWindowLayoutChangedEventArgs e);

    public partial class CameraControl : UserControl
    {
        /// <summary>
        /// 播放窗口大小改变事件
        /// </summary>
        public event PlayWindowLayoutChangedHandle PlayWindowLayoutChangedEvent;

        /// <summary>
        /// 摄像头播放窗口布局
        /// </summary>
        private Point windowLayout = new Point(1, 1);

        /// <summary>
        /// 当前选中窗口序号
        /// </summary>
        private int m_nCurSelWindowIndex = 0;

        /// <summary>
        /// 播放窗口列表
        /// </summary>
        private List<PlayWindow> m_subFormList = new List<PlayWindow>();

        /// <summary>
        /// 获取或设置摄像头播放窗口布局
        /// </summary>
        [Category("播放窗口")]
        [Description("指定播放窗口的布局")]
        public Point WindowLayout
        {
            get { return windowLayout; }
            set
            {
                if (windowLayout == value)
                {
                    return;
                }
                else
                {
                    windowLayout = value;

                    if (null != PlayWindowLayoutChangedEvent)
                    {
                        PlayWindowLayoutChangedEvent(this, new PlayWindowLayoutChangedEventArgs(value));
                    }

                    // 修改属性后，触发窗口重绘
                    Invalidate();
                }
            }
        }

        public CameraControl()
        {
            InitializeComponent();

            // 默认有一个播放窗口
            PlayWindow playWindow = new PlayWindow(0, this, this.Location.X, this.Location.Y, this.Width, this.Height);
            // 注册播放窗口右键菜单事件
            playWindow.OpenContextMenuEvent += new OpenContextMenuHandler(OnOpenContextMenu);
            m_subFormList.Add(playWindow);

            // 注册窗口布局改变事件
            this.PlayWindowLayoutChangedEvent += new PlayWindowLayoutChangedHandle(OnPlayWindowLayoutChanged);
        }

        /// <summary>
        /// 初始化摄像头参数
        /// </summary>
        /// <param name="CameraParamList">摄像头参数列表</param>
        public void InitCameraParam(CameraBase[] CameraParamList)
        {
            int nCount = (m_subFormList.Count >= CameraParamList.Length) ? CameraParamList.Length : m_subFormList.Count;

            PlayWindow tmpPlayWindow = null;

            for (int i = 0; i < nCount; i++)
            {
                tmpPlayWindow = m_subFormList[i];
                tmpPlayWindow.Init(CameraParamList[i]);
            }
        }

        /// <summary>
        /// 打开所有摄像头
        /// </summary>
        public void OpenAll()
        {
            PlayWindow tmpPlayWindow = null;

            for (int i = 0; i < m_subFormList.Count; i++)
            {
                tmpPlayWindow = m_subFormList[i];

                try
                {
                    tmpPlayWindow.Close();

                    if (tmpPlayWindow.Open())
                    {
                        tmpPlayWindow.Play();
                    }
                }
                catch (CameraException e)
                {
                    MessageBox.Show(e.OprErrorMessage);
                }
            }
        }

        /// <summary>
        /// 打开指定窗口序号的摄像头（摄像头参数已指定）
        /// </summary>
        /// <param name="nPlayWindowIndex">窗口序号</param>
        /// <returns></returns>
        public bool Open(int nPlayWindowIndex)
        {
            try
            {
                PlayWindow tmpPlayWindow = m_subFormList[nPlayWindowIndex];

                // 关闭正在播放的
                tmpPlayWindow.Close();

                // 重新打开
                if (!tmpPlayWindow.Open())
                {
                    return false;
                }

                return tmpPlayWindow.Play();
            }
            catch (CameraException e)
            {
                MessageBox.Show(e.OprErrorMessage);
            }
            catch (Exception e)
            {
                MessageBox.Show(e.Message);
            }

            return false;
        }

        /// <summary>
        /// 打开指定窗口位置的摄像头
        /// </summary>
        /// <param name="x">窗口行坐标</param>
        /// <param name="y">窗口列坐标</param>
        /// <returns></returns>
        public bool Open(UInt32 x, UInt32 y)
        {
            try
            {
                UInt32 nPlayWindowIndex = y * (UInt32)windowLayout.Y + x;
                PlayWindow tmpPlayWindow = m_subFormList[(int)nPlayWindowIndex];

                tmpPlayWindow.Close();

                if (!tmpPlayWindow.Open())
                {
                    return false;
                }

                return tmpPlayWindow.Play();
            }
            catch (CameraException e)
            {
                MessageBox.Show(e.OprErrorMessage);
            }
            catch (Exception e)
            {
                MessageBox.Show(e.Message);
            }

            return false;
        }

        /// <summary>
        /// 打开指定窗口序号的摄像头
        /// </summary>
        /// <param name="nPlayWindowIndex"></param>
        /// <returns></returns>
        public bool Open(int nPlayWindowIndex, object obj)
        {
            try
            {
                PlayWindow tmpPlayWindow = m_subFormList[nPlayWindowIndex];

                tmpPlayWindow.Close();

                if (!tmpPlayWindow.Open(obj))
                {
                    return false;
                }

                return tmpPlayWindow.Play();
            }
            catch (CameraException e)
            {
                MessageBox.Show(e.OprErrorMessage);
            }
            catch (Exception e)
            {
                MessageBox.Show(e.Message);
            }

            return false;
        }


        /// <summary>
        /// 打开指定窗口位置的摄像头
        /// </summary>
        /// <param name="x">窗口行坐标</param>
        /// <param name="y">窗口列坐标</param>
        /// <returns></returns>
        public bool Open(UInt32 x, UInt32 y, object obj)
        {
            try
            {
                UInt32 nPlayWindowIndex = y * (UInt32)windowLayout.Y + x;
                PlayWindow tmpPlayWindow = m_subFormList[(int)nPlayWindowIndex];

                tmpPlayWindow.Close();

                if (!tmpPlayWindow.Open(obj))
                {
                    return false;
                }

                return tmpPlayWindow.Play();
            }
            catch (CameraException e)
            {
                MessageBox.Show(e.OprErrorMessage);
            }
            catch (Exception e)
            {
                MessageBox.Show(e.Message);
            }

            return false;
        }

        /// <summary>
        /// 关闭所有摄像头
        /// </summary>
        public void CloseAll()
        {
            PlayWindow tmpPlayWindow = null;

            for (int i = 0; i < m_subFormList.Count; i++)
            {
                tmpPlayWindow = m_subFormList[i];

                try
                {
                    tmpPlayWindow.Close();
                }
                catch (CameraException e)
                {
                    MessageBox.Show(e.OprErrorMessage);
                }
            }
        }

        /// <summary>
        /// 关闭指定窗口序号的摄像头
        /// </summary>
        /// <param name="nWindowIndex"></param>
        /// <returns></returns>
        public bool Close(int nPlayWindowIndex)
        {
            try
            {
                PlayWindow tmpPlayWindow = m_subFormList[nPlayWindowIndex];
                return tmpPlayWindow.Close();
            }
            catch (CameraException e)
            {
                MessageBox.Show(e.OprErrorMessage);
            }
            catch (Exception e)
            {
                MessageBox.Show(e.Message);
            }

            return false;
        }

        /// <summary>
        /// 关闭指定窗口位置的摄像头
        /// </summary>
        /// <param name="x">窗口行坐标</param>
        /// <param name="y">窗口列坐标</param>
        /// <returns></returns>
        public bool Close(UInt32 x, UInt32 y)
        {
            try
            {
                UInt32 nPlayWindowIndex = y * (UInt32)windowLayout.Y + x;
                PlayWindow tmpPlayWindow = m_subFormList[(int)nPlayWindowIndex];
                return tmpPlayWindow.Close();
            }
            catch (CameraException e)
            {
                MessageBox.Show(e.OprErrorMessage);
            }
            catch (Exception e)
            {
                MessageBox.Show(e.Message);
            }

            return false;
        }

        /// <summary>
        /// 指定窗口序号摄像头抓拍
        /// </summary>
        /// <param name="nWindowIndex">窗口序号</param>
        /// <param name="strPicFile">存储路径</param>
        /// <returns></returns>
        public bool CaptureImage(int nPlayWindowIndex, string strPicFile)
        {
            try
            {
                PlayWindow tmpPlayWindow = m_subFormList[nPlayWindowIndex];
                return tmpPlayWindow.CaptureImage(strPicFile);
            }
            catch (CameraException e)
            {
                MessageBox.Show(e.OprErrorMessage);
            }
            catch (Exception e)
            {
                MessageBox.Show(e.Message);
            }

            return false;
        }

        /// <summary>
        /// 指定窗口位置摄像头抓拍
        /// </summary>
        /// <param name="x">窗口行坐标</param>
        /// <param name="y">窗口列坐标</param>
        /// <param name="strPicFile">存储路径</param>
        /// <returns></returns>
        public bool CaptureImage(UInt32 x, UInt32 y, string strPicFile)
        {
            try
            {
                UInt32 nPlayWindowIndex = y * (UInt32)windowLayout.Y + x;
                PlayWindow tmpPlayWindow = m_subFormList[(int)nPlayWindowIndex];
                return tmpPlayWindow.CaptureImage(strPicFile);
            }
            catch (CameraException e)
            {
                MessageBox.Show(e.OprErrorMessage);
            }
            catch (Exception e)
            {
                MessageBox.Show(e.Message);
            }

            return false;
        }

        /// <summary>
        /// 改变子窗口大小
        /// </summary>
        void ResizeSubWindow()
        {
            PlayWindow tmpPlayWindow = null;

            Size tmpSize = this.Size;
            tmpSize.Width = this.Width / (Int32)windowLayout.X;
            tmpSize.Height = this.Height / (Int32)windowLayout.Y;

            for (int j = 0; j < windowLayout.Y; j++)
            {
                for (int i = 0; i < windowLayout.X; i++)
                {
                    tmpPlayWindow = m_subFormList[j * (int)windowLayout.Y + i];
                    tmpPlayWindow.ReSizeWindow(i * tmpSize.Width, j * tmpSize.Height, tmpSize.Width, tmpSize.Height);
                }
            }
        }

        private void OnPlayWindowLayoutChanged(object sender, PlayWindowLayoutChangedEventArgs e)
        {
            // 处理播放窗口改变后的显示
            PlayWindow tmpPlayWindow = null;

            // 先关闭已创建的
            if (0 != m_subFormList.Count)
            {
                for (int i = 0; i < m_subFormList.Count; i++)
                {
                    tmpPlayWindow = m_subFormList[i];
                    tmpPlayWindow.Close();
                    tmpPlayWindow.Dispose();
                }

                m_subFormList.Clear();
            }

            // 获取父容器大小
            Size tmpSize = this.Size;
            tmpSize.Width = this.Width / windowLayout.X;
            tmpSize.Height = this.Height / windowLayout.Y;

            int nWindowIndex = 0;

            for (int j = 0; j < windowLayout.Y; j++)
            {
                for (int i = 0; i < windowLayout.X; i++)
                {
                    nWindowIndex = j * (int)windowLayout.Y + i;
                    tmpPlayWindow = new PlayWindow(nWindowIndex, this, i * tmpSize.Width, j * tmpSize.Height, tmpSize.Width, tmpSize.Height);
                    tmpPlayWindow.OpenContextMenuEvent += new OpenContextMenuHandler(OnOpenContextMenu);
                    m_subFormList.Add(tmpPlayWindow);
                }
            }
        }

        private void CameraControl_SizeChanged(object sender, EventArgs e)
        {
            ResizeSubWindow();
        }

        private void OnOpenContextMenu(object sender, PlayWindowEventArgs args)
        {
            m_nCurSelWindowIndex = args.WindowIndex;
            this.contextMenuStrip_Control.Show(MousePosition.X, MousePosition.Y);
        }

        private void ToolStripMenuItem_Open_Click(object sender, EventArgs e)
        {
            Open(m_nCurSelWindowIndex);
        }

        private void ToolStripMenuItem_Close_Click(object sender, EventArgs e)
        {
            Close(m_nCurSelWindowIndex);
        }

        private void ToolStripMenuItem_OpenAll_Click(object sender, EventArgs e)
        {
            OpenAll();
        }

        private void ToolStripMenuItem_CloseAll_Click(object sender, EventArgs e)
        {
            CloseAll();
        }
    }

    public class PlayWindowLayoutChangedEventArgs : EventArgs
    {
        public readonly PointF WindowSizeArgs = new PointF();

        public PlayWindowLayoutChangedEventArgs(PointF p)
        {
            WindowSizeArgs = p;
        }
    }
}
